#include <iostream>
#include <cassert>
#include <any>
#include <string>

class Any
{
private:
    //抽象类，父类
    class holder {
        public:
            virtual ~holder() {}
            virtual const std::type_info& type() = 0;
            virtual holder *clone() = 0;
    };
    //实际存储数据的子类
    template<class T>
    class placeholder:public holder{
    public:
        T _val; 
    public:
        placeholder(const T& val):_val(val){}
        // 获取子类对象保存的数据类型
        virtual const std::type_info& type() { return typeid(T); }
        // 针对当前的对象自身，克隆出一个新的子类对象
        virtual holder *clone() { return new placeholder(_val); }
    };

    //指向存储数据子类的指针
    holder *_content;
public:
    Any():_content(nullptr){}
    template<typename T>
    Any(const T& val):_content(new placeholder<T>(val)){}
    Any(const Any& other):_content(other._content ? other._content->clone():nullptr) {}
    ~Any(){ delete _content; }

    //用于辅助进行赋值运算符重载
    Any& swap(Any& other)
    {
        std::swap(_content,other._content);
        return *this;
    }
    //赋值运算符重载
    template<typename T>
    Any& operator = (const T& val){
        Any(val).swap(*this);
        return *this;
    }
    Any& operator = (const Any& other){
        Any(other).swap(*this);
        return *this;
    }

    //获取Any存储的数据的引用
    template<typename T>
    T& get(){
        //安全检查，全包安全转换
        assert(_content->type()==typeid(T));
        return ((placeholder<T>*)_content)->_val;
    }
};

class Test{
    public:
        Test() {std::cout << "构造" << std::endl;}
        Test(const Test &t) {std::cout << "拷贝" << std::endl;}
        ~Test() {std::cout << "析构" << std::endl;}
};

void myAny_test()
{
    Any a;
    {
        Test t;
        a = t;
    }
    
    a = 10;
    int pa = a.get<int>();
    std::cout << pa << std::endl;
    a = std::string("hello");
    std::string ps = a.get<std::string>();
    std::cout << ps << std::endl;
}

void use_std_any()
{
    std::any a;
    a=100;
    int val=std::any_cast<int&>(a);
    std::cout<<val<<std::endl;
    
    a=std::string("hello");  // 明确存储为 std::string
    std::string str=std::any_cast<std::string&>(a);
    std::cout<<str<<std::endl;
}

int main()
{
    use_std_any();
    return 0;
}